const http = require("http")
const fs = require("fs")
const path = require("path")

const os = require('os')

const { env } = require("process")
require("dotenv").config({
  path: path.resolve(__dirname, `../.env.${env.NODE_ENV}`)
})

const runTime = new Date().getTime()

const filePath = path.resolve(__dirname + "/initscript")
const fileName = "/index.js"
const addNewFileData = "/userScript.js"
let addPlgScruptUrl = ""
let addOptionsScriptUrl = ""
let addPopupScriptUrl = ""
// const OSS = require("ali-oss")

const region = "obs-gdgz"
const S3 = require("@aws-sdk/client-s3");

const { S3Client, PutObjectCommand } = S3;

const s3Client = new S3Client({
  region,
  endpoint: `http://${region}.cucloud.cn`,
  credentials: {
    accessKeyId: '7ED9472E49BA4F4CB2F871C5EA46100E4528',
    secretAccessKey: '661EE67B043D49068547851560CF7EA87421'
  },
});

console.log('环境', env.NODE_ENV)
// const client = new OSS({
//   // yourregion填写Bucket所在地域。以华东1（杭州）为例，Region填写为oss-cn-hangzhou。
//   // region: "obs-gdjy",
//   // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
//   accessKeyId: '7ED9472E49BA4F4CB2F871C5EA46100E4528',//import.meta.env.VITE_OSS_ACCESS_KEY_ID,
//   accessKeySecret: '661EE67B043D49068547851560CF7EA87421',// import.meta.env.VITE_OSS_ACCESS_KEY_SECRET,
//   bucket: "wtplugd",
//   endpoint: 'obs-gdjy.cucloud.cn',
//   // 设置签名加密方式
//   cname : true , 
// })
const filtUtils = function () {
  const optionsScript = ["options."]
  const popupScript = ["popup."]
  const schearfilepath = `./build/chrome-mv3-${env.BUILD_FILE_NAME}`
  let splitfilepath = ''

  let splitStopStr = ''
  let filepath = ''

  if (os.type() == 'Windows_NT') {
    //windows平台
    splitfilepath = `build\\chrome-mv3-${env.BUILD_FILE_NAME}`
    console.log('window')
    splitStopStr = "==/UserScript==\r\n"
    filepath = `${path.resolve(__dirname, `.${schearfilepath}`)}\\`

  }
  if (os.type() == 'Darwin') {
    splitfilepath = `build/chrome-mv3-${env.BUILD_FILE_NAME}`
    console.log('mac')
    splitStopStr = "==/UserScript=="
    filepath = `${path.resolve(__dirname, `.${schearfilepath}`)}/`


    //mac
  }
  if (os.type() == 'Linux') {
    splitfilepath = `build/chrome-mv3-${env.BUILD_FILE_NAME}`
    //Linux平台
    console.log('Linux平台')
    splitStopStr = "==/UserScript=="
    filepath = `${path.resolve(__dirname, `.${schearfilepath}`)}`

  }

  const plgHeaterText = `\n${env.PLG_HEATER}${filepath}`

  const resfiletype = ["js", "css"]
  const scriptHeader = {
    start: "==UserScript==",
    stop: "==/UserScript=="
  }
  let addUserHeaderScript = ""
  let addUserScriptContent = ""
  let userScriptAllContent = ""
  const excludeFile = [
    "icon",
    "background",
    "index.js",
    "static",
    "manifest.json"
  ]
  this.getAllPloginFiles = () => {
    const itemsInfo = this.getAllFilesInfo(schearfilepath)
    itemsInfo.forEach(async (filte) => {
      const fls = filte.path.split(splitfilepath)[1]
      const filename = fls.replace("\\", "")
      let addKey = true
      for (let i = 0; i < excludeFile.length; i++) {
        if (fls.includes(optionsScript[i])) {
          const getmactfile = fls.split(".")
          if (resfiletype.includes(getmactfile[getmactfile.length - 1])) {
            if (env.NODE_ENV === "development") {
              addOptionsScriptUrl =
                addOptionsScriptUrl + plgHeaterText + filename
            } else {
              addOptionsScriptUrl =
                addOptionsScriptUrl + `\n${env.PLG_HEATER}` + filename
            }
          }
        }
        if (fls.includes(popupScript[i])) {
          const getmactfile = fls.split(".")
          if (resfiletype.includes(getmactfile[getmactfile.length - 1])) {
            if (env.NODE_ENV === "development") {
              addPopupScriptUrl = addPopupScriptUrl + plgHeaterText + filename
            } else {
              addPopupScriptUrl =
                addPopupScriptUrl + `\n${env.PLG_HEATER}` + filename
            }
          }
        }
        if (
          fls.includes(excludeFile[i]) ||
          fls.includes(optionsScript[i]) ||
          fls.includes(popupScript[i])
        ) {
          addKey = false
          break
        }
      }
      if (addKey) {
        const getmactfile = fls.split(".")
        if (resfiletype.includes(getmactfile[getmactfile.length - 1])) {

          if (env.NODE_ENV === "development") {
            addPlgScruptUrl = addPlgScruptUrl + plgHeaterText + filename
          } else {
            addPlgScruptUrl = addPlgScruptUrl + `\n${env.PLG_HEATER}` + runTime + '.' + filename

          }
          const headers = {
            // 指定Object的存储类型。
            "x-oss-storage-class": "Standard",
            // 指定Object的访问权限。
            "x-oss-object-acl": "public-read",
            // 通过文件URL访问文件时，指定以附件形式下载文件，下载后的文件名称定义为example.txt。
            "Content-Disposition": `attachment; filename="${filename}"`,
            // 设置Object的标签，可同时设置多个标签。
            "x-oss-tagging": `FileName=${filename}`,
            // 指定PutObject操作时是否覆盖同名目标Object。此处设置为true，表示禁止覆盖同名Object。
            "x-oss-forbid-overwrite": "false"
          }
          if (env.NODE_ENV === 'production' || env.NODE_ENV === 'test') {
            const upfile = await this.putfile(
              filepath + filename,
              headers,
              filename
            )
            //   console.log("upfile", upfile)
          }
        }
      }
    })
  }
  this.putfile = async (filepath, headers, filename) => {
    console.log('filename', path.normalize(filepath))

    const command = new PutObjectCommand({
      // 填写Bucket名称。
      Bucket: "wtplugd",
      // 填写OSS文件完整路径和本地文件的完整路径。OSS文件完整路径中不能包含Bucket名称。
      Key: `plugin/content/${runTime + '.' + filename}`,
      // 指定文件内容或Buffer。
      Body: fs.readFileSync(path.normalize(filepath)),
      // headers
      ACL: 'public-read',
    });
    try {
      const response = await s3Client.send(command)
        ;
      console.log("Object uploaded successfully", response);
      return response
    } catch (error) {
      console.error("Error uploading object:", error);
    }
    // try {
    //   // 填写OSS文件完整路径和本地文件的完整路径。OSS文件完整路径中不能包含Bucket名称。
    //   // 如果本地文件的完整路径中未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件。


    //   // const result = await client.put(
    //   //   `plugin/content/${runTime + '.' + filename}`,
    //   //   path.normalize(filepath),
    //   //   // 自定义headers
    //   //   { headers }
    //   // )


    //     console.log('上传进度---', result)
    //   return result
    // } catch (e) {
    //   console.log('上传图片', e)
    // }
  }
  this.getAllFilesInfo = (dirPath) => {
    const itemsInfo = []
    function traverseDirectory(currentPath) {
      const items = fs.readdirSync(currentPath)
      for (const item of items) {
        const itemPath = path.join(currentPath, item)
        const stat = fs.statSync(itemPath)

        if (stat.isFile() || stat.isDirectory()) {
          itemsInfo.push({
            name: item,
            path: itemPath,
            size: stat.size,
            createdAt: stat.ctime,
            modifiedAt: stat.mtime,
            isDirectory: stat.isDirectory()
          })
        }
        if (stat.isDirectory()) {
          traverseDirectory(itemPath)
        }
      }
    }

    traverseDirectory(dirPath)
    return itemsInfo
  }
  this.steUserScript = () => {
    // console.log('filePath+fileName', filePath+fileName)
    const userScript = this.readUserScript(fileName)
    let headertext = userScript.substring(
      userScript.indexOf(scriptHeader.start) + scriptHeader.start.length,
      userScript.indexOf(scriptHeader.stop)
    )
    addUserHeaderScript = `\n// ${scriptHeader.start}\n${headertext}${addPlgScruptUrl}\n// ${scriptHeader.stop}`
    // console.log('addUserHeaderScript', addUserHeaderScript)
    addUserScriptContent = userScript.split(splitStopStr)[1]
    // console.log('addUserScriptContent', addUserScriptContent, runTime)
    const addScriptContentSchear =
      addUserScriptContent ||
      ` console.error('没有可用脚本，或者缺少// ==UserScript==  // ==/UserScript==, 关键字')`
    userScriptAllContent = `${addUserHeaderScript}\n${addScriptContentSchear}`
    if (!addUserScriptContent) {
      throw new Error(
        "没有可用脚本，或者缺少// ==UserScript==  // ==/UserScript==, 关键字"
      )
    }
    fs.writeFileSync(filePath + addNewFileData, userScriptAllContent, "utf8")
    return userScriptAllContent
  }
  this.readUserScript = (getname) => {
    const userScript = fs.readFileSync(filePath + getname, "utf8")
    return userScript
  }
}

const startServer = function () {
  const server = http.createServer((req, res) => {
    switch (req.url) {
      case "/getfilename":
        res.setHeader("Content-Type", "application/text")
        res.end("***")
        break
      case "/getcontents":
        try {
          const fileEdx = new filtUtils()
          res.setHeader("Content-Type", getMimeType(filePath + fileName))
          if (env.NODE_ENV === "production" || env.NODE_ENV === "test") {
            res.setHeader(
              "Content-Type",
              getMimeType(filePath + addNewFileData)
            )
            res.end(fileEdx.readUserScript(addNewFileData))
          }
          if (env.NODE_ENV === "development") {
            res.end(fileEdx.steUserScript())
          }
          //   const data = fs.readFileSync(filePath+fileName)
          //   res.setHeader("Content-Type", getMimeType(filePath+fileName))
          //   res.end(data)
        } catch (err) {
          console.error(`无法读取文件 ${filePath + fileName}:`, err)
          res.statusCode = 404
          res.end()
        }
        break
      default:
        res.statusCode = 404
        res.end()
        break
    }
  })

  // 获取文件类型对应的MIME类型
  function getMimeType(fileName) {
    const extname = path.extname(fileName).slice(1)
    switch (extname) {
      case "html":
        return "text/html"
      case "css":
        return "text/css"
      case "js":
        return "application/javascript"
      default:
        return ""
    }
  }

  // 开始侦听指定的端口号
  server.listen(env.APP_PORT, () => {
    console.log("文件服务已启动！", env.APP_PORT)
  })
}

const init = function () {
  // 启动服务
  startServer()
  // 获取所有脚本路径
  const fileEdx = new filtUtils()
  fileEdx.getAllPloginFiles()

  //   console.log("内容脚本", addPlgScruptUrl)
  //   console.log("选项页脚本", addOptionsScriptUrl)
  //   console.log("点击Popup弹窗脚本", addPopupScriptUrl)

  fileEdx.steUserScript()
}
init()
